using System;
using System.Text;
using IDeal.Extensions;
using IDeal.Models;
using IDeal.Net;

namespace IDeal.Services
{
// ReSharper disable InconsistentNaming
    public class IDealServices : IIDealServices
// ReSharper restore InconsistentNaming
    {
        public IDealServices(IConfigurationAccessor configurationAccessor, ICryptoServices cryptoServices, ITypeActivator activator)
        {
            CryptoServices = cryptoServices;
            Activator      = activator;
            Configuration  = configurationAccessor.GetConfiguration();
            _webClient     = new XmlWebClient(this);
        }

        private readonly IXmlWebClient _webClient;
        public Configuration Configuration { get; private set; }
        public ICryptoServices CryptoServices { get; private set; }
        public ITypeActivator Activator { get; private set; }

        public DirectoryResponse GetIssuers()
        {
            var request = new DirectoryRequest {MerchantId = Configuration.MerchantId, SubId = Configuration.SubId};
            return _webClient.SendRequest<DirectoryRequest, DirectoryResponse>(request);
        }

        public TransactionResponse CreateTransaction(TransactionRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.MerchantId))
            {
                request.MerchantId = Configuration.MerchantId;
            }

            if (string.IsNullOrWhiteSpace(request.SubId))
            {
                request.SubId = Configuration.SubId;
            }

            return _webClient.SendRequest<TransactionRequest, TransactionResponse>(request);
        }

        public StatusResponse RequestStatus(string transactionId)
        {
            var request = new StatusRequest
            {
                MerchantId = Configuration.MerchantId,
                SubId = Configuration.SubId,
                TransactionId = transactionId
            };

            var response = _webClient.SendRequest<StatusRequest, StatusResponse>(request);
            var signatureFields = GetSignatureSource(response);

            CryptoServices.ValidateSignature(response.Signature, signatureFields);
            return response;
        }

        public string GenerateEntranceCode()
        {
            return Guid.NewGuid().ToString().Replace("-", "");
        }

        private static string GetSignatureSource(StatusResponse response)
        {
            var signatureFields = response.CreateDateTimeStamp.ToIDealFormat() + response.TransactionId + response.Status;

            if (response.Status == TransactionStatus.Success)
                signatureFields += response.ConsumerAccountNumber;
            return signatureFields;
        }
    }
}